/*
 * Copyright (C) Jahia Ltd. All rights reserved.
 *
 * This software is published under the terms of the Jahia Open Software
 * License version 1.1, a copy of which has been included with this
 * distribution in the LICENSE.txt file.
 */
package org.jahia.sqlprofiler;

import org.json.JSONArray;
import org.json.JSONException;

import java.util.StringTokenizer;

/**
 * <p>Title: Contains a P6Spy Log entry information, which may be an SQL
 * query, a result set log, etc... </p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2003</p>
 * <p>Company: Jahia Ltd</p>
 *
 * @author Serge Huber
 * @version 1.0
 */

public class QueryEntry implements Comparable {
    private long time = 0;
    private long elapsedTime = 0;
    private String preparedSQL;
    private String sqlStatement;
    private String category;
    private String connectionID;
    private int receptionRank = 0;

    public QueryEntry() {
    }

    public QueryEntry(String p6EncodedText) {
        parseP6Encoding(p6EncodedText);
    }

    public long getTime() {
        return time;
    }

    public void setTime(long time) {
        this.time = time;
    }

    public long getElapsedTime() {
        return elapsedTime;
    }

    public void setElapsedTime(long elapsedTime) {
        this.elapsedTime = elapsedTime;
    }

    public String getPreparedSQL() {
        return preparedSQL;
    }

    public void setPreparedSQL(String preparedSQL) {
        this.preparedSQL = preparedSQL;
    }

    public String getSqlStatement() {
        return sqlStatement;
    }

    public void setSqlStatement(String sqlStatement) {
        this.sqlStatement = sqlStatement;
    }

    public String getCategory() {
        return category;
    }

    public void setCategory(String category) {
        this.category = category;
    }

    public String getConnectionID() {
        return connectionID;
    }

    public void setConnectionID(String connectionID) {
        this.connectionID = connectionID;
    }

    public int getReceptionRank() {
        return receptionRank;
    }

    public void setReceptionRank(int receptionRank) {
        this.receptionRank = receptionRank;
    }

    private void parseP6EncodingString(String p6EncodedText) {
            /* * Format taken from com.p6spy.engine.logging.appender.FormattedLogger.java
         * String logEntry = now + "|"+ elapsed + "|"+(connectionId==-1 ? "" : String.valueOf(connectionId))+"|"+category+"|"+prepared+"|"+sql;*/

        StringTokenizer tokenizer = new StringTokenizer(p6EncodedText, "|", true);
        String now = tokenizer.nextToken();
        if (now.equals("|")) {
            now = null;
        } else {
            tokenizer.nextToken();
        }
        String elapsed = tokenizer.nextToken();
        if (elapsed.equals("|")) {
            elapsed = null;
        } else {
            tokenizer.nextToken();
        }
        String connectionID = tokenizer.nextToken();
        if (connectionID.equals("|")) {
            connectionID = null;
        } else {
            tokenizer.nextToken();
        }
        String category = tokenizer.nextToken();
        if (category.equals("|")) {
            category = null;
        } else {
            tokenizer.nextToken();
        }
        String prepared = tokenizer.nextToken();
        if (prepared.equals("|")) {
            prepared = null;
        } else {
            tokenizer.nextToken();
        }
        String sqlStatement = "";
        if (tokenizer.hasMoreTokens()) {
            sqlStatement = tokenizer.nextToken();
        }

        this.time = Long.parseLong(now);
        this.elapsedTime = Long.parseLong(elapsed);
        this.connectionID = connectionID;
        this.category = category;
        this.preparedSQL = prepared;
        this.sqlStatement = sqlStatement;

    }
    private void parseP6Encoding(String p6EncodedText) {
        if(p6EncodedText.charAt(0)=='['){
            parseJsonString(p6EncodedText);
        } else {
            parseP6EncodingString(p6EncodedText);
        }
    }

    private void parseJsonString(String p6EncodedText){
        try {
            JSONArray json = new JSONArray(p6EncodedText);
            int index = 0;
            this.time = json.getLong(index++);
            this.elapsedTime = json.getLong(index++);
            this.connectionID = json.getString(index++);
            this.category = json.getString(index++);
            this.preparedSQL = json.getString(index++);
            this.sqlStatement = json.getString(index);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    public int compareTo(Object o) {
        QueryEntry right = (QueryEntry) o;
        Long leftTime = new Long(getTime());
        Long rightTime = new Long(right.getTime());
        int timeCompare = leftTime.compareTo(rightTime);
        if (timeCompare != 0) {
            return timeCompare;
        } else {
            return new Integer(receptionRank).compareTo(new Integer(right.getReceptionRank()));
        }
    }

    public boolean equals(Object o) {
        return (compareTo(o) == 0);
    }

    public int hashCode() {
        return (Long.toString(time) + Integer.toString(receptionRank)).hashCode();
    }

}